package com.zmzncs.lmtc.module.promotion.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zmzncs.lmtc.common.pojo.enums.optionalvalue.promotion.MonthRentTypeEnum;
import com.zmzncs.lmtc.common.util.ExceptionUtil;
import com.zmzncs.lmtc.module.park.dao.ParkInfoDao;
import com.zmzncs.lmtc.module.park.pojo.park_info.ParkInfo;
import com.zmzncs.lmtc.module.promotion.dao.*;
import com.zmzncs.lmtc.module.promotion.pojo.customize_rule.CustomizeRule;
import com.zmzncs.lmtc.module.promotion.pojo.customize_rule.CustomizeRuleUpdateForm;
import com.zmzncs.lmtc.module.promotion.pojo.customize_rule_fee_scale.CustomizeRuleFeeScale;
import com.zmzncs.lmtc.module.promotion.pojo.customize_rule_fee_scale.CustomizeRuleFeeScaleDTO;
import com.zmzncs.lmtc.module.promotion.pojo.customize_rule_fee_scale.CustomizeRuleFeeScaleMobileVO;
import com.zmzncs.lmtc.module.promotion.pojo.month_rule_fee_scale.MonthRuleFeeScaleDTO;
import com.zmzncs.lmtc.module.promotion.service.CustomizeRuleService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 任建波
 * @since 2020-08-13
 */
@Service
public class CustomizeRuleServiceImpl extends ServiceImpl<CustomizeRuleDao, CustomizeRule> implements CustomizeRuleService {

    @Autowired
    CustomizeRuleDao customizeRuleDao;
    @Autowired
    CustomizeRuleFeeScaleDao customizeRuleFeeScaleDao;
    @Autowired
    MonthRuleFeeScaleMapper monthRuleFeeScaleMapper;
    @Autowired
    ParkInfoDao parkInfoDao;
    /**
     * 编辑定制规则
     */
    @Override
    @Transactional
    public void updateCustomizeRule(CustomizeRuleUpdateForm customizeRuleUpdateForm) {
        //  删除旧数据
        CustomizeRule customizeRule = new CustomizeRule();
        customizeRule.setIsDeleted(1);
        customizeRuleDao.update(customizeRule, null);

        CustomizeRuleFeeScale customizeRuleFeeScale = new CustomizeRuleFeeScale();
        customizeRuleFeeScale.setIsDeleted(1);
        customizeRuleFeeScaleDao.update(customizeRuleFeeScale, null);

        //  ******添加2个停车场数据
        CustomizeRule twoParkCustomizeRule = new CustomizeRule();
        twoParkCustomizeRule.setCreateUserId(3);
        twoParkCustomizeRule.setStatus(customizeRuleUpdateForm.getTwoParkStatus().getCode());
        twoParkCustomizeRule.setParkNum(2);
        customizeRuleDao.insert(twoParkCustomizeRule);

        CustomizeRuleFeeScale twoParkMonthCustomizeRuleFeeScale = new CustomizeRuleFeeScale();
        twoParkMonthCustomizeRuleFeeScale.setCustomizeRuleId(twoParkCustomizeRule.getId());
        twoParkMonthCustomizeRuleFeeScale.setMonthRentType(MonthRentTypeEnum.MONTH.getCode());
        twoParkMonthCustomizeRuleFeeScale.setDiscountRate(customizeRuleUpdateForm.getTwoParkMonthDiscountRate());
        customizeRuleFeeScaleDao.insert(twoParkMonthCustomizeRuleFeeScale);

        CustomizeRuleFeeScale twoParkQuarterCustomizeRuleFeeScale = new CustomizeRuleFeeScale();
        twoParkQuarterCustomizeRuleFeeScale.setCustomizeRuleId(twoParkCustomizeRule.getId());
        twoParkQuarterCustomizeRuleFeeScale.setMonthRentType(MonthRentTypeEnum.QUARTER.getCode());
        twoParkQuarterCustomizeRuleFeeScale.setDiscountRate(customizeRuleUpdateForm.getTwoParkQuarterDiscountRate());
        customizeRuleFeeScaleDao.insert(twoParkQuarterCustomizeRuleFeeScale);

        CustomizeRuleFeeScale twoParkYearCustomizeRuleFeeScale = new CustomizeRuleFeeScale();
        twoParkYearCustomizeRuleFeeScale.setCustomizeRuleId(twoParkCustomizeRule.getId());
        twoParkYearCustomizeRuleFeeScale.setMonthRentType(MonthRentTypeEnum.YEAR.getCode());
        twoParkYearCustomizeRuleFeeScale.setDiscountRate(customizeRuleUpdateForm.getTwoParkYearDiscountRate());
        customizeRuleFeeScaleDao.insert(twoParkYearCustomizeRuleFeeScale);

        //  ******添加3个停车场数据
        CustomizeRule threeParkCustomizeRule = new CustomizeRule();
        threeParkCustomizeRule.setCreateUserId(3);
        threeParkCustomizeRule.setStatus(customizeRuleUpdateForm.getThreeParkStatus().getCode());
        threeParkCustomizeRule.setParkNum(3);
        customizeRuleDao.insert(threeParkCustomizeRule);

        CustomizeRuleFeeScale threeParkMonthCustomizeRuleFeeScale = new CustomizeRuleFeeScale();
        threeParkMonthCustomizeRuleFeeScale.setCustomizeRuleId(threeParkCustomizeRule.getId());
        threeParkMonthCustomizeRuleFeeScale.setMonthRentType(MonthRentTypeEnum.MONTH.getCode());
        threeParkMonthCustomizeRuleFeeScale.setDiscountRate(customizeRuleUpdateForm.getThreeParkMonthDiscountRate());
        customizeRuleFeeScaleDao.insert(threeParkMonthCustomizeRuleFeeScale);

        CustomizeRuleFeeScale threeParkQuarterCustomizeRuleFeeScale = new CustomizeRuleFeeScale();
        threeParkQuarterCustomizeRuleFeeScale.setCustomizeRuleId(threeParkCustomizeRule.getId());
        threeParkQuarterCustomizeRuleFeeScale.setMonthRentType(MonthRentTypeEnum.QUARTER.getCode());
        threeParkQuarterCustomizeRuleFeeScale.setDiscountRate(customizeRuleUpdateForm.getThreeParkQuarterDiscountRate());
        customizeRuleFeeScaleDao.insert(threeParkQuarterCustomizeRuleFeeScale);

        CustomizeRuleFeeScale threeParkYearCustomizeRuleFeeScale = new CustomizeRuleFeeScale();
        threeParkYearCustomizeRuleFeeScale.setCustomizeRuleId(threeParkCustomizeRule.getId());
        threeParkYearCustomizeRuleFeeScale.setMonthRentType(MonthRentTypeEnum.YEAR.getCode());
        threeParkYearCustomizeRuleFeeScale.setDiscountRate(customizeRuleUpdateForm.getThreeParkYearDiscountRate());
        customizeRuleFeeScaleDao.insert(threeParkYearCustomizeRuleFeeScale);

        //  ******添加4个停车场数据
        CustomizeRule fourParkCustomizeRule = new CustomizeRule();
        fourParkCustomizeRule.setCreateUserId(3);
        fourParkCustomizeRule.setStatus(customizeRuleUpdateForm.getFourParkStatus().getCode());
        fourParkCustomizeRule.setParkNum(4);
        customizeRuleDao.insert(fourParkCustomizeRule);

        CustomizeRuleFeeScale fourParkMonthCustomizeRuleFeeScale = new CustomizeRuleFeeScale();
        fourParkMonthCustomizeRuleFeeScale.setCustomizeRuleId(fourParkCustomizeRule.getId());
        fourParkMonthCustomizeRuleFeeScale.setMonthRentType(MonthRentTypeEnum.MONTH.getCode());
        fourParkMonthCustomizeRuleFeeScale.setDiscountRate(customizeRuleUpdateForm.getFourParkMonthDiscountRate());
        customizeRuleFeeScaleDao.insert(fourParkMonthCustomizeRuleFeeScale);

        CustomizeRuleFeeScale fourParkQuarterCustomizeRuleFeeScale = new CustomizeRuleFeeScale();
        fourParkQuarterCustomizeRuleFeeScale.setCustomizeRuleId(fourParkCustomizeRule.getId());
        fourParkQuarterCustomizeRuleFeeScale.setMonthRentType(MonthRentTypeEnum.QUARTER.getCode());
        fourParkQuarterCustomizeRuleFeeScale.setDiscountRate(customizeRuleUpdateForm.getFourParkQuarterDiscountRate());
        customizeRuleFeeScaleDao.insert(fourParkQuarterCustomizeRuleFeeScale);

        CustomizeRuleFeeScale fourParkYearCustomizeRuleFeeScale = new CustomizeRuleFeeScale();
        fourParkYearCustomizeRuleFeeScale.setCustomizeRuleId(fourParkCustomizeRule.getId());
        fourParkYearCustomizeRuleFeeScale.setMonthRentType(MonthRentTypeEnum.YEAR.getCode());
        fourParkYearCustomizeRuleFeeScale.setDiscountRate(customizeRuleUpdateForm.getFourParkYearDiscountRate());
        customizeRuleFeeScaleDao.insert(fourParkYearCustomizeRuleFeeScale);

        //  ******添加5个停车场数据
        CustomizeRule fiveParkCustomizeRule = new CustomizeRule();
        fiveParkCustomizeRule.setCreateUserId(3);
        fiveParkCustomizeRule.setStatus(customizeRuleUpdateForm.getFiveParkStatus().getCode());
        fiveParkCustomizeRule.setParkNum(5);
        customizeRuleDao.insert(fiveParkCustomizeRule);

        CustomizeRuleFeeScale fiveParkMonthCustomizeRuleFeeScale = new CustomizeRuleFeeScale();
        fiveParkMonthCustomizeRuleFeeScale.setCustomizeRuleId(fiveParkCustomizeRule.getId());
        fiveParkMonthCustomizeRuleFeeScale.setMonthRentType(MonthRentTypeEnum.MONTH.getCode());
        fiveParkMonthCustomizeRuleFeeScale.setDiscountRate(customizeRuleUpdateForm.getFiveParkMonthDiscountRate());
        customizeRuleFeeScaleDao.insert(fiveParkMonthCustomizeRuleFeeScale);

        CustomizeRuleFeeScale fiveParkQuarterCustomizeRuleFeeScale = new CustomizeRuleFeeScale();
        fiveParkQuarterCustomizeRuleFeeScale.setCustomizeRuleId(fiveParkCustomizeRule.getId());
        fiveParkQuarterCustomizeRuleFeeScale.setMonthRentType(MonthRentTypeEnum.QUARTER.getCode());
        fiveParkQuarterCustomizeRuleFeeScale.setDiscountRate(customizeRuleUpdateForm.getFiveParkQuarterDiscountRate());
        customizeRuleFeeScaleDao.insert(fiveParkQuarterCustomizeRuleFeeScale);

        CustomizeRuleFeeScale fiveParkYearCustomizeRuleFeeScale = new CustomizeRuleFeeScale();
        fiveParkYearCustomizeRuleFeeScale.setCustomizeRuleId(fiveParkCustomizeRule.getId());
        fiveParkYearCustomizeRuleFeeScale.setMonthRentType(MonthRentTypeEnum.YEAR.getCode());
        fiveParkYearCustomizeRuleFeeScale.setDiscountRate(customizeRuleUpdateForm.getFiveParkYearDiscountRate());
        customizeRuleFeeScaleDao.insert(fiveParkYearCustomizeRuleFeeScale);
    }

    /**
     * 计算价格
     */
    @Override
    public CustomizeRuleFeeScaleMobileVO computePrice(List<String> parkIds) {
        List<MonthRuleFeeScaleDTO> monthRulePaytypeAllList = new ArrayList<>();
        //  校验停车场收费规则
        for(String parkId: parkIds){
            List<MonthRuleFeeScaleDTO> monthRulePaytypeList = monthRuleFeeScaleMapper.getMonthRuleFeeScaleByParkId(parkId);
            if(monthRulePaytypeList.size() == 0){
                ExceptionUtil.businessException("停车场" + parkId + "没有开启月租服务");
            }

            ParkInfo parkInfo = parkInfoDao.selectById(parkId);
            if(parkInfo == null || !parkInfo.getIsShow().equals(1)){
                ExceptionUtil.businessException("停车场" + parkId + "已停止服务或不存在");
            }
            monthRulePaytypeAllList.addAll(monthRulePaytypeList);
        }

        //  *********************************停车场折率
        //  根据停车场数量查询定制规则
        List<CustomizeRuleFeeScaleDTO> customizeRulePaytypes = customizeRuleFeeScaleDao.getCustomizeRuleFeeScaleByParkNum(parkIds.size());
        //  月付折率
        CustomizeRuleFeeScaleDTO customizeRuleMonthPaytype = customizeRuleMonthPaytype(customizeRulePaytypes, MonthRentTypeEnum.MONTH);
        //  季付折率
        CustomizeRuleFeeScaleDTO customizeRuleQuarterPaytype = customizeRuleMonthPaytype(customizeRulePaytypes, MonthRentTypeEnum.QUARTER);
        //  年付折率
        CustomizeRuleFeeScaleDTO customizeRuleYearPaytype = customizeRuleMonthPaytype(customizeRulePaytypes, MonthRentTypeEnum.YEAR);


        //  *********************************计算停车场费用
        //  月付
        List<MonthRuleFeeScaleDTO> monthRulePaytype = monthRulePaytype(monthRulePaytypeAllList, MonthRentTypeEnum.MONTH);
        //  季付
        List<MonthRuleFeeScaleDTO> quarterRulePaytype = monthRulePaytype(monthRulePaytypeAllList, MonthRentTypeEnum.QUARTER);
        //  年付
        List<MonthRuleFeeScaleDTO> yearRulePaytype = monthRulePaytype(monthRulePaytypeAllList, MonthRentTypeEnum.YEAR);


        //  月付金额计算：除去价格最高的停车场。剩余停车场费用总和
        BigDecimal monthTotalAmount = totalAmount(monthRulePaytype, customizeRuleMonthPaytype, MonthRentTypeEnum.MONTH);
        //  季付金额计算：除去价格最高的停车场。剩余停车场费用总和
        BigDecimal quarterTotalAmount = totalAmount(quarterRulePaytype, customizeRuleQuarterPaytype, MonthRentTypeEnum.QUARTER);
        //  年付金额计算：除去价格最高的停车场。剩余停车场费用总和
        BigDecimal yearTotalAmount = totalAmount(yearRulePaytype, customizeRuleYearPaytype, MonthRentTypeEnum.YEAR);

        //  根据停车场数量查询定制规则
        LambdaQueryWrapper<CustomizeRule> lambdaQueryWrapper = new LambdaQueryWrapper();
        lambdaQueryWrapper.eq(CustomizeRule::getParkNum, parkIds.size());
        CustomizeRule customizeRule = customizeRuleDao.selectOne(lambdaQueryWrapper);

        CustomizeRuleFeeScaleMobileVO customizeRuleFeeScaleMobileVO = new CustomizeRuleFeeScaleMobileVO();
        customizeRuleFeeScaleMobileVO.setMonthTotalAmount(monthTotalAmount);
        customizeRuleFeeScaleMobileVO.setQuarterTotalAmount(quarterTotalAmount);
        customizeRuleFeeScaleMobileVO.setYearTotalAmount(yearTotalAmount);
        customizeRuleFeeScaleMobileVO.setCustomizeRuleId(customizeRule.getId());
        return customizeRuleFeeScaleMobileVO;
    }

    /**
     * 月、季、年收费标准
     */
    List<MonthRuleFeeScaleDTO> monthRulePaytype(List<MonthRuleFeeScaleDTO> monthRulePaytypes, MonthRentTypeEnum paytype){
        //  收费标准
        List<MonthRuleFeeScaleDTO> paytypes = new ArrayList<>();
        for(MonthRuleFeeScaleDTO monthRuleFeeScaleDTO : monthRulePaytypes){
            if(monthRuleFeeScaleDTO.getMonthRentType().intValue() == paytype.getCode()){
                paytypes.add(monthRuleFeeScaleDTO);
            }
        }

        //  降序
        Collections.sort(paytypes, new Comparator<MonthRuleFeeScaleDTO>() {
            @Override
            public int compare(MonthRuleFeeScaleDTO m1, MonthRuleFeeScaleDTO m2) {
                BigDecimal diff = m2.getAmount().subtract(m1.getAmount());
                if (diff.compareTo(BigDecimal.ZERO) > 0) {
                    return 1;
                }else if (diff.compareTo(BigDecimal.ZERO) < 0) {
                    return -1;
                }
                return 0; //相等为0
            }
        });
        return paytypes;
    }

    /**
     *  订单支付折率
     */
    CustomizeRuleFeeScaleDTO customizeRuleMonthPaytype(List<CustomizeRuleFeeScaleDTO> customizeRulePaytypes, MonthRentTypeEnum paytype){
        CustomizeRuleFeeScaleDTO customizeRulePaytype = new CustomizeRuleFeeScaleDTO();
        for(CustomizeRuleFeeScaleDTO customizeRuleFeeScaleDTO : customizeRulePaytypes){
            //  月付折率
            if(customizeRuleFeeScaleDTO.getMonthRentType().intValue() == paytype.getCode()){
                customizeRulePaytype = customizeRuleFeeScaleDTO;
            }
        }
        return customizeRulePaytype;
    }

    /**
     * 总金额
     */
    BigDecimal totalAmount(List<MonthRuleFeeScaleDTO> monthRulePaytypes, CustomizeRuleFeeScaleDTO customizeRulePaytype, MonthRentTypeEnum paytype){
        BigDecimal totalAmount = new BigDecimal(0);
        //  除最高价格停车场外的其他停车场费用总和
        for(int i=0; i<monthRulePaytypes.size(); i++){
            if(i == 0){
                continue;
            }
            if(monthRulePaytypes.get(i).getMonthRentType().intValue() == paytype.getCode()){
                totalAmount = totalAmount.add(monthRulePaytypes.get(i).getAmount());
            }
        }

        //  除去价格最高的停车场后剩余停车场费用总和 * 折率
        totalAmount = totalAmount.multiply(customizeRulePaytype.getDiscountRate().divide(new BigDecimal(100)));
        totalAmount = monthRulePaytypes.get(0).getAmount().add(totalAmount);

        return totalAmount;
    }

}
